package com.changhong.framework.sdfs.namenode.server.directory;

import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 文件目录管理实现组件
 * @author Summer
 */
public class DefaultDirectoryManager implements DirectoryManager{

    /**
     * 内存中的文件目录树
     */
    private final DataNodeDirectory dirTree=new DataNodeDirectory("/");
    private final ReentrantReadWriteLock reentrantReadWriteLock=new ReentrantReadWriteLock();
    private final ReentrantReadWriteLock.WriteLock writeLock=reentrantReadWriteLock.writeLock();
    private final ReentrantReadWriteLock.ReadLock readLock=reentrantReadWriteLock.readLock();


    @Override
    public boolean createDir(String path) throws Exception {
        writeLock.lock();
        try{
            String[] pathes = path.split("/");
            DataNodeDirectory parent = dirTree;
            for(String splitedPath : pathes) {
                if("".equals(splitedPath.trim())) {
                    continue;
                }
                DataNodeDirectory dir = findDirectory(parent, splitedPath);
                if(dir != null) {
                    parent = dir;
                    continue;
                }
                DataNodeDirectory child = new DataNodeDirectory(splitedPath);
                parent.addChild(child);
            }
            return true;
        }
        catch (Exception e){
            return false;
        }
        finally {
            writeLock.unlock();
        }
    }

    /**
     * 对文件目录树递归查找目录
     * @param dirTree 文件
     * @param path 路径
     * @return
     */
    private DataNodeDirectory findDirectory(DataNodeDirectory dirTree, String path) {
        if(dirTree.getChildren().size() == 0) {
            return null;
        }
        DataNodeDirectory resultDir;
        for(TreeNode child : dirTree.getChildren()) {
            if(child instanceof DataNodeDirectory) {
                DataNodeDirectory childDir = (DataNodeDirectory) child;
                if((childDir.getPath().equals(path))) {
                    return childDir;
                }
                resultDir = findDirectory(childDir, path);
                if(resultDir != null) {
                    return resultDir;
                }
            }
        }
        return null;
    }
}
